package com.matrix.toolutils.common

import android.util.JsonReader
import android.util.JsonToken
import android.util.JsonWriter
import com.google.gson.Gson
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import com.google.gson.JsonParseException
import com.google.gson.JsonParser
import com.google.gson.JsonPrimitive
import com.google.gson.JsonSerializationContext
import com.google.gson.JsonSerializer
import com.google.gson.TypeAdapter
import com.google.gson.reflect.TypeToken
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import org.json.JSONTokener
import java.io.IOException
import java.lang.reflect.Type
import java.util.*

/**
 * 作者：Administrator
 * 日期：2024/9/14 16:08
 * 描述：
 */
object GsonUtil {
    private var gson = Gson()

    /**
     * object转成json
     *
     * @param object
     *
     * @return
     */
    fun toJson(obj: Any?): String? {
        return gson.toJson(obj)
    }

    /**
     * object转成json
     *
     * @param object
     * @param typeOfT
     *
     * @return
     */
    fun toJson(obj: Any?, typeOfT: Type?): String? {
        return gson.toJson(obj, typeOfT)
    }

    /**
     * json转成bean
     *
     * @param jsonStr
     * @param cls
     * @param <T>
     *
     * @return
    </T> */
    fun <T> toBean(jsonStr: String?, cls: Class<T>?): T {
        return gson.fromJson(jsonStr, cls)
    }

    /**
     * json转成bean
     *
     * @param jsonStr
     *
     * @return
     */
    fun <T> toBean(jsonStr: String?, typeOfT: Type?): T {
        return gson.fromJson(jsonStr, typeOfT)
    }

    /**
     * object转成bean
     *
     * @param <T>
     *
     *
     * @param object
     * @return
    </T> */
    fun <T> toBean(obj: Any?, cls: Class<T>?): T {
        return gson.fromJson(gson.toJson(obj), cls)
    }

    /**
     * object转成bean
     *
     * @param object
     * @param typeOfT
     * @param <T>
     *
     * @return
    </T> */
    fun <T> toBean(obj: Any?, typeOfT: Type?): T {
        return gson.fromJson(gson.toJson(obj), typeOfT)
    }

    /**
     * JSONObject转成bean
     *
     * @param jsonObject
     * @param cls
     * @param <T>
     *
     * @return
    </T> */
    fun <T> toBean(jsonObject: JSONObject, cls: Class<T>?): T {
        return gson.fromJson(jsonObject.toString(), cls)
    }

    /**
     * JSONObject转成bean
     *
     * @param jsonObject
     * @param typeOfT
     * @param <T>
     *
     * @return
    </T> */
    fun <T> toBean(jsonObject: JSONObject, typeOfT: Type?): T {
        return gson.fromJson(jsonObject.toString(), typeOfT)
    }

    /**
     * JSONArray转成bean
     *
     * @param jsonArray
     * @param cls
     * @param <T>
     *
     * @return
    </T> */
    fun <T> toBean(jsonArray: JSONArray, cls: Class<T>?): T {
        return gson.fromJson(jsonArray.toString(), cls)
    }

    /**
     * JSONArray转成bean
     *
     * @param jsonArray
     * @param typeOfT
     * @param <T>
     *
     * @return
    </T> */
    fun <T> toBean(jsonArray: JSONArray, typeOfT: Type?): T {
        return gson.fromJson(jsonArray.toString(), typeOfT)
    }

    /**
     * object转成JSONObject
     *
     * @param object
     *
     * @return
     *
     * @throws JSONException
     */
    @Throws(JSONException::class)
    fun toJSONObject(obj: Any?): JSONObject? {
        return JSONObject(gson.toJson(obj))
    }

    /**
     * json转成JSONObject
     *
     * @param jsonStr
     *
     * @return
     *
     * @throws JSONException
     */
    @Throws(JSONException::class)
    fun toJSONObject(jsonStr: String?): JSONObject? {
        return JSONObject(jsonStr)
    }

    /**
     * object转成JSONArray
     *
     * @param object
     *
     * @return
     *
     * @throws JSONException
     */
    @Throws(JSONException::class)
    fun toJSONArray(obj: Any?): JSONArray? {
        return JSONArray(toJson(obj))
    }

    /**
     * json转成JSONArray
     *
     * @param jsonStr
     *
     * @return
     *
     * @throws JSONException
     */
    @Throws(JSONException::class)
    fun toJSONArray(jsonStr: String?): JSONArray? {
        return JSONArray(jsonStr)
    }

    /**
     * Collection转成JSONArray
     *
     * @param collection
     *
     * @return
     */
    @Throws(JSONException::class)
    fun toJSONArray(collection: Collection<*>?): JSONArray? {
        return JSONArray(toJson(collection))
    }

    /**
     * json转成list
     *
     * @param jsonStr
     *
     * @return
     */
    fun <T> toList(jsonStr: String?): List<T>? {
        return toBean(jsonStr, object : TypeToken<List<T>?>() {}.type)
    }

    /**
     * json转成map
     *
     * @param jsonStr
     *
     * @return
     */
    fun <T> toMap(jsonStr: String?): MutableMap<String, T> {
        return toBean(jsonStr, object : TypeToken<Map<String?, T>?>() {}.type)
    }

    /**
     * Json转List集合,遇到解析不了的，就使用这个
     */
    fun <T> toList(json: String?, cls: Class<T>?): List<T>? {
        val mList: MutableList<T> = ArrayList()
        val array = JsonParser().parse(json).asJsonArray
        for (elem in array) {
            mList.add(gson.fromJson(elem, cls))
        }
        return mList
    }

    /**
     * 判断是否json字符串
     *
     * @param content
     *
     * @return
     */
    fun isJson(content: String?): Boolean {
        try {
            val obj = JSONTokener(content).nextValue()
            return obj is JSONObject || obj is JSONArray
        } catch (ignored: JSONException) {
        }
        return false
    }

    /**
     * 将json中的null替换成""
     *
     * 用法：
     * GsonBuilder gb = new GsonBuilder();
     * gb.registerTypeAdapter(String.class, new StringConverter());
     * Gson gson = gb.create();
     */
    abstract class StringConverter : JsonSerializer<String?>,
        JsonDeserializer<String?> {
        fun serialize(
            src: String,
            typeOfSrc: Type,
            context: JsonSerializationContext
        ): JsonElement {
            return if (src == null) {
                JsonPrimitive("")
            } else {
                JsonPrimitive(src)
            }
        }

        @Throws(JsonParseException::class)
        override fun deserialize(
            json: JsonElement,
            typeOfT: Type,
            context: JsonDeserializationContext
        ): String {
            return json.asJsonPrimitive.asString
        }
    }

    /**
     * 将json中的null替换成""
     * 自定义String适配器
     */
    abstract class StringTypeAdapter : TypeAdapter<String?>() {

        @Throws(IOException::class)
        fun read(reader: JsonReader): String {
            if (reader.peek() == JsonToken.NULL) {
                reader.nextNull()
                return ""
            }
            return reader.nextString()
        }

        @Throws(IOException::class)
        fun write(writer: JsonWriter, value: String) {
            if (value == null) {
                // 在这里处理null改为空字符串
                writer.value("")
                return
            }
            writer.value(value)
        }
    }
}